﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using System.Reflection;
using System.Text;
using System.IO;
using System.Net;
using System.Threading;
using System.ComponentModel;
using System.Security.Principal;
using InfoJetSoft.Service.Entity;
using InfoJetSoft.Service.Util;

//CID 1104 //2012.02.21 //Begin
namespace InfoJetSoft.Service.Worker
{
    class DataObjectSPQueryWorker
    {
        public static void queryDoc(Form form, DataSPListAdapter spListAdapter)
		{
            UnauthorizedConnection loginConnection = DataWebUnauthorizedWorker.findLoginConnection(form, spListAdapter);
            queryDoc(form, spListAdapter, loginConnection);
		}

        public static void queryDoc(Form form, DataSPListAdapter spListAdapter, UnauthorizedConnection loginConnection)
        {
            XmlNode queryNode = buildQueryNode(form);

            //CID 1109 //2012.02.23 //Begin
            XmlNode listNode = queryList(form, spListAdapter, queryNode, loginConnection);
            //CID 1109 //2012.02.23 //End
            if (listNode == null)
            {
                throw new InfoJetException("Cannot load SharePoint List " + spListAdapter.Name, "DOSPQ");
            }

            XmlNamespaceManager nsManager = new XmlNamespaceManager(listNode.OwnerDocument.NameTable);
            nsManager.AddNamespace("sp", "http://schemas.microsoft.com/sharepoint/soap/");
            nsManager.AddNamespace("z", "#RowsetSchema");
            nsManager.AddNamespace("y", "http://schemas.microsoft.com/sharepoint/soap/ois/");
            nsManager.AddNamespace("w", "http://schemas.microsoft.com/WebPart/v2");
            nsManager.AddNamespace("d", "http://schemas.microsoft.com/sharepoint/soap/directory/");

            XmlNodeList rowElementList = listNode.SelectNodes(".//z:row", nsManager);

            XmlElement dataFieldsElement = DOMUtil.selectOneNode(form.XmlDoc, "/dfs:myFields/dfs:dataFields", form.XmlNsResolver) as XmlElement;
            DOMUtil.removeChildNodes(dataFieldsElement);

            string itemNamespaceUri = "http://schemas.microsoft.com/office/infopath/2009/WSSList/cmeDataFields";
            string itemNamespacePrefix = form.XmlNsResolver.LookupPrefix(itemNamespaceUri);
            
            System.Text.RegularExpressions.Regex CheckLookup = new System.Text.RegularExpressions.Regex("^\\d+;#");
            foreach (XmlElement rowElement in rowElementList)
            {
                //CID 0703 //2010.12.19 //Begin
                XmlElement groupElement = form.XmlDoc.CreateElement(itemNamespacePrefix, "SharePointListItem_RW", itemNamespaceUri);
                foreach (DataField field in spListAdapter.FieldList)
                {
                    string val = rowElement.GetAttribute("ows_" + field.SharePointName);
                    if ((val == null || val.Length <= 0) && field.SharePointName.Equals("Title"))
                    {
                        val = rowElement.GetAttribute("ows_LinkTitle");
                    }
                    if (CheckLookup.IsMatch((string)val))
                    {
                        val = val.Substring(val.IndexOf("#") + 1);
                    }
                    XmlElement valElement = groupElement.OwnerDocument.CreateElement(itemNamespacePrefix, field.InfoPathName, itemNamespaceUri);
                    valElement.InnerText = val;
                    groupElement.AppendChild(valElement);
                }
                dataFieldsElement.AppendChild(groupElement);
            }

            FormBuildFieldListByXMLDocWorker.buildFieldListByXMLDoc(form, false);
            SchemaPSVI.clearXsiNil(form);
        }

        //CID 1104 //2012.02.21 //Begin
        private static XmlNode buildQueryNode(Form form)
        {
            XmlElement typeElement = DOMUtil.selectOneNode(form.XmlDoc, "/dfs:myFields/dfs:queryFields/q:SharePointListItem_RW/q:Type", form.XmlNsResolver) as XmlElement;

            XmlDocument queryDoc = new XmlDocument();
            queryDoc.LoadXml("<Query><Where><Eq><FieldRef Name='Type'></FieldRef><Value Type='Text'></Value></Eq></Where></Query>");
            XmlElement valueElement = queryDoc.SelectSingleNode("/Query/Where/Eq/Value") as XmlElement;
            valueElement.InnerText = typeElement.InnerText;

            return queryDoc.DocumentElement;
        }
        //CID 1104 //2012.02.21 //End

        //CID 1109 //2012.02.23 //Begin
        private static XmlNode queryList(Form form, DataSPListAdapter spListAdapter, XmlNode query, UnauthorizedConnection loginConnection)
        {
            XmlNode listNode = null;
            FormConfigListForm listFormConfig = null;
            if (form.Manifest.FormConfiguration != null)
            {
                listFormConfig = form.Manifest.FormConfiguration.ListFormConfig;
            }
            if (listFormConfig != null && listFormConfig.SharePointSiteURL != null)
            {
                if (listFormConfig.MockLookupField != null)
                {
                    XmlElement fieldRefElement = query.SelectSingleNode("/Query/Where/Eq/FieldRef") as XmlElement;
                    fieldRefElement.SetAttribute("Name", listFormConfig.MockLookupField);
                }

                InfoJetSoft.SharePointLists.Lists lists = new InfoJetSoft.SharePointLists.Lists();
                //CID 1109 //2012.02.23 //Begin
                lists.Url = listFormConfig.SharePointSiteURL + "_vti_bin/Lists.asmx";
                //CID 1109 //2012.02.23 //End
                lists.PreAuthenticate = true;
                //CID 0370 //2009.07.17 //Begin
                //CID 1109 //2012.02.23 //Begin
                /*
                if (listFormConfig.SharePointSiteURL != null)
                {
                    System.Net.CredentialCache cache = new System.Net.CredentialCache();
                    cache.Add(new Uri("http://hp:82"), "NTLM", new System.Net.NetworkCredential("Administrator", "", "hp"));
                    lists.Credentials = cache;
                }
                else
                {
                    lists.Credentials = DataWebUnauthorizedWorker.getCredentialCache(form.HttpContext, new Uri(lists.Url), loginConnection);
                }
                */ 
                lists.Credentials = DataWebUnauthorizedWorker.getCredentialCache(form.HttpContext, new Uri(lists.Url), loginConnection);
                //CID 1109 //2012.02.23 //End
                //CID 0370 //2009.07.17 //End
                //CID 0962 //2011.06.27 //Begin
                int webTimeout = ConfigUtil.WebTimeout();
                if (webTimeout >= 0)
                {
                    lists.Timeout = webTimeout;
                }
                //CID 0962 //2011.06.27 //End

                //获取所有的列.
                XmlDocument xmlDoc = new System.Xml.XmlDocument();
                XmlNode ndViewFields = xmlDoc.CreateNode(XmlNodeType.Element, "ViewFields", "");

                //CID 1109 //2012.02.23 //Begin
                if (listFormConfig.LookupDataSourceGUID != null)
                {
                    listNode = lists.GetListItems(listFormConfig.LookupDataSourceGUID, null, query, ndViewFields, null, null, null);
                }
                else
                {
                    listNode = lists.GetListItems(spListAdapter.Guid, null, query, ndViewFields, null, null, null);
                }
                //CID 1109 //2012.02.23 //End

                if (form.HttpContext.Session != null)
                {
                    form.HttpContext.Session[spListAdapter.Id] = loginConnection;
                }

                //CID 1109 //2012.02.23 //Begin
                if (listFormConfig.MockLookupField != null)
                {
                    DataObjectSPQueryWorker.FormatLookupField(listFormConfig, listNode);
                }
                //CID 1109 //2012.02.23 //End
            }
            else
            {
                listNode = GetListItems(form, spListAdapter, query, loginConnection);
            }
            return listNode;
        }
        //CID 1109 //2012.02.23 //End

        //CID 1109 //2012.02.23 //Begin
        public static void FormatLookupField(FormConfigListForm listFormConfig, XmlNode listNode)
        {
            string owsMockLookupField = "ows_" + listFormConfig.MockLookupField;
            List<XmlElement> rowElementList = QuickSelectUtil.SearchChildElementsByLocalName(listNode as XmlElement, "row");
            foreach (XmlElement rowElement in rowElementList)
            {
                string lookupValue = rowElement.GetAttribute(owsMockLookupField);
                rowElement.RemoveAttribute(owsMockLookupField);
                rowElement.SetAttribute("ows_Type", lookupValue);
            }
        }
        //CID 1109 //2012.02.23 //End
        
        public static XmlNode GetListItems(Form form, DataSPListAdapter spListAdapter, XmlNode query, UnauthorizedConnection loginConnection)
        {
            XmlDocument xmlDoc = new System.Xml.XmlDocument();
            XmlNode ndViewFields = xmlDoc.CreateNode(XmlNodeType.Element, "ViewFields", "");

            try
            {
                string dataProviderAssembly = ConfigUtil.ListFormDataProviderAssembly();
                Assembly dpAssembly = Assembly.Load(dataProviderAssembly);
                Type dpType = null;
                foreach (Type type in dpAssembly.GetTypes())
                {
                    bool found = false;
                    foreach (Attribute attr in type.GetCustomAttributes(true))
                    {
                        if (attr is DescriptionAttribute)
                        {
                            DescriptionAttribute descAttr = (DescriptionAttribute)attr;
                            string desc = descAttr.Description.Trim();
                            if (desc.Equals("InfoJet ListForm, DataProviderClass"))
                            {
                                found = true;
                                break;
                            }
                        }
                    }
                    if (found)
                    {
                        dpType = type;
                    }
                }
                MethodInfo getListItemsMethod = dpType.GetMethod("GetListItems", BindingFlags.Public | BindingFlags.Static);
                object[] parameters = { spListAdapter.Guid, query, ndViewFields };
                object result = getListItemsMethod.Invoke(null, parameters);
                XmlNode resultNode = result as XmlNode;
                return resultNode;
            }
            catch (Exception e)
            {
                FileLog.log(e);
                return null;
            }
        }
    }
}
//CID 1104 //2012.02.21 //End